

package yf.mall.service.impl.app;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yf.response.RRException;
import com.yf.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yf.mall.dao.KolOrderDao;
import yf.mall.entity.*;
import yf.mall.mapper.KolProductStatExtMapper;
import yf.mall.utils.MapperUtils;
import yf.mall.component.app.AppDyAuthCompoent;
import yf.mall.component.helper.ProductHelper;
import yf.mall.dao.KolProductDao;
import yf.mall.dao.KolShopDao;
import yf.mall.dysdk.model.DyToken;
import yf.mall.dysdk.model.product.DyProduct;
import yf.mall.dysdk.service.DyAllianceApiService;
import yf.mall.entity.custom.KolProductParam;
import yf.mall.mapper.KolProductExtMapper;
import yf.mall.mapper.KolShopExtMapper;
import yf.mall.service.app.KolProductService;
import yf.mall.vo.KolProductVo;
import yf.mall.vo.app.product.KolProductSumVo;
import yf.mall.vo.app.request.ProductNotifyRequest;
import yf.mall.vo.down.KolProductDown;
import yf.mall.vo.up.KolProductUp;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 账户记录Service实现类
 *
 *
 * 
 * @date Tue Jul 18 14:30:26 CST 2023
 */
@Slf4j
@Service
public class KolProductServiceImpl extends BaseServiceImpl<KolProductEntity> implements KolProductService {

    @Resource
    private KolProductDao dao;

    @Resource
    private KolShopDao kolShopDao;

    @Resource
    private DyAllianceApiService dyAllianceApiService;

    @Resource
    private AppDyAuthCompoent appDyAuthCompoent;

    @Resource
    private KolProductExtMapper kolProductExtMapper;

    @Resource
    private KolShopExtMapper kolShopExtMapper;

    @Resource
    private KolProductStatExtMapper kolProductStatExtMapper;


    @Autowired
    public void setDao(KolProductDao dao) {
        this.dao = dao;
        super.setBaseDao(dao);
    }


    @Override
    public List<KolProductVo> findVo(KolProductVo vo) {
        return dao.findVo(vo);
    }

    @Override
    public KolProductVo getVo(Long id) {
        return dao.getVo(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveVo(KolProductVo vo) {
        return dao.save(vo.getEntity());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateVo(KolProductVo vo) {
        return dao.update(vo.getEntity());
    }


    @Override
    public void downLoad(HttpServletResponse response, List<KolProductVo> list) {
        try {
            List<KolProductDown> datas = list.stream().map(item -> new KolProductDown(item)).collect(Collectors.toList());
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("测试", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), KolProductDown.class).sheet("模板").doWrite(datas);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public void downLoadSum(HttpServletResponse response, List<KolProductSumVo> datas) {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("测试", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), KolProductSumVo.class).sheet("模板").doWrite(datas);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void upload(InputStream file) {
        EasyExcel.read(file, KolProductUp.class, new UploadDataListener()).sheet().doRead();
    }


    class UploadDataListener extends AnalysisEventListener<KolProductUp> {


        @Override
        @Transactional(rollbackFor = Exception.class)
        public void invoke(KolProductUp upVo, AnalysisContext analysisContext) {
            saveVo(upVo.toVo());
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {

        }

    }


    /**内部方法**/


    /**
     * 外部方法实现
     **/
    @Override
    public PageInfo<KolProductEntity> page(KolProductParam query) {
        PageHelper.startPage(query.getPageNumber(), query.getPageSize());
        KolProductEntityExample example = buildExample(query);
        List<KolProductEntity> entityList = kolProductExtMapper.selectByExample(example);
        return new PageInfo(entityList);
    }

    private KolProductEntityExample buildExample(KolProductParam query) {
        KolProductEntityExample example = new KolProductEntityExample();
        KolProductEntityExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(query.getTitle())) {
            criteria.andTitleLike("%" + query.getTitle() + "%");
        }
        if (CollectionUtils.isNotEmpty(query.getProductIds())) {
            criteria.andIdIn(query.getProductIds());
        }
        if (query.getRecommend() != null) {
            criteria.andRecommendEqualTo(query.getRecommend());
        }
        if (query.getMaterialType() != null) {
            criteria.andMaterialTypeEqualTo(query.getMaterialType());
        }
        if (query.getMarketType() != null) {
            criteria.andMarketTypeEqualTo(query.getMarketType());
        }
        if (CollectionUtils.isNotEmpty(query.getFirstCid())) {
            // 使用内部分类？
            criteria.andTypeIn(query.getFirstCid());
        }
        if (query.isHasMaterial()) {
            MapperUtils.addCriterion(criteria, "id in (select pid from app_product_material)");
        }
        if (query.getUpdateTime() != null) {
            criteria.andUpdateTimeLessThan(query.getUpdateTime());
        }
        if (StringUtils.isNotBlank(query.getOrderBy())) {
            example.setOrderByClause(query.getOrderBy());
        }
        return example;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void notifyDyProductToDb(Long userId, ProductNotifyRequest request) {
        log.info("同步抖音商品到数据库，userId={},request={}", userId, request);
        if (request == null) {
            return;
        }
        DyToken dyToken = appDyAuthCompoent.getMasterTokenByUser(userId);
        List<DyProduct> dyProducts = dyAllianceApiService.productDetail(dyToken, request.getProductIds(), true, true, true);

        dyProducts.forEach(dyProduct -> {
            KolProductEntity kolProductEntity = ProductHelper.convertProductDyToDb(dyProduct);
            mergeShop(dyProduct);
            KolProductEntity dbProduct = dao.get(kolProductEntity.getId());
            dbProduct.setMarketType(request.getMarketType());
            dbProduct.setType(request.getType());
            if (dbProduct == null) {
                kolProductExtMapper.insertSelective(kolProductEntity);
            } else {
                kolProductExtMapper.updateByPrimaryKey(kolProductEntity);
            }
        });
    }

   public void mergeShop(DyProduct dyProduct){
        KolShopEntity shopEntity = ProductHelper.convertShopDyToDb(dyProduct);
        KolShopEntity dbShop = kolShopDao.get(shopEntity.getId());
        if (dbShop == null) {
            kolShopExtMapper.insertSelective(shopEntity);
        } else {
            kolShopExtMapper.updateByPrimaryKey(shopEntity);
        }
    }

    @Override
    public KolProductEntity reqDyProduct(Long id) {
        DyToken dyToken = appDyAuthCompoent.getDefaultToken();//默认找一个合适的
        List<DyProduct> dyProducts = dyAllianceApiService.productDetail(dyToken, Arrays.asList(id), true, true, true);
        if (dyProducts == null || dyProducts.isEmpty()) {
            throw new RRException("没有获取到产品数据!");
        }
        DyProduct dyProduct = dyProducts.get(0);
        mergeShop(dyProduct);
        KolProductEntity kolProductEntity = ProductHelper.convertProductDyToDb(dyProducts.get(0));
        return kolProductEntity;
    }

    @Override
    public List<KolProductEntity> findAll() {
        return dao.findAll();
    }

    @Override
    public List<KolProductEntity> findByIds(List<Long> ids) {
        return dao.findByIds(ids);
    }

    @Override
    public List<KolProductStatEntity> findStatByProductIds(List<Long> productIds) {
        KolProductStatEntityExample example = new KolProductStatEntityExample();
        example.createCriteria().andPidIn(productIds);
        return kolProductStatExtMapper.selectByExample(example);
    }

    @Override
    public KolProductStatEntity findStatByProductId(Long productId) {
        KolProductStatEntityExample example = new KolProductStatEntityExample();
        example.createCriteria().andPidEqualTo(productId);
        return kolProductStatExtMapper.selectByExample(example).stream().findFirst().orElse(null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveProductStat(KolProductStatEntity kolProductStatEntity) {
        int result = kolProductStatExtMapper.updateByPrimaryKey(kolProductStatEntity);
        if (result <= 0) {
            return kolProductStatExtMapper.insertSelective(kolProductStatEntity) > 0;
        }
        return true;
    }

    @Resource
    private KolOrderDao kolOrderDao;

    @Override
    public List<KolProductSumVo> sum() {
        List<KolProductSumVo> vos = kolOrderDao.sumProduct();
        if(vos.isEmpty()){
            return vos;
        }
        List<KolProductEntity> products = dao.findByIds(vos.stream().map(KolProductSumVo::getId).collect(Collectors.toList()));
        Map<Long,String> productMap = products.stream().collect(Collectors.toMap(KolProductEntity::getId,KolProductEntity::getTitle));
        vos.forEach(vo->{
            vo.setName(productMap.get(vo.getId()));
        });
        return vos;
    }
}
